package sharetime.enumerations;

import java.io.ObjectStreamException;

import sharetime.user.domain.User;
import sharetime.user.service.IPermissionDelegate;

public enum Permission {
	VIEW("VIEW") {
		public boolean checkAgainst(IPermissionDelegate delegate, User user,
				Object target) {
			return delegate.canView(user, target);
		}
	},
	CREATE("CREATE") {
		public boolean checkAgainst(IPermissionDelegate delegate, User user,
				Object target) {
			return delegate.canCreate(user, target);
		}
	},
	EDIT("EDIT") {
		public boolean checkAgainst(IPermissionDelegate delegate, User user,
				Object target) {
			return delegate.canEdit(user, target);
		}
	},
	SET_PERMISSIONS("SET_PERMISSIONS") {
		public boolean checkAgainst(IPermissionDelegate delegate, User user,
				Object target) {
			return delegate.canSetPermissions(user, target);
		}
	},
	REMOVE("REMOVE") {
		public boolean checkAgainst(IPermissionDelegate delegate, User user,
				Object target) {
			return delegate.canRemove(user, target);
		}
	};

	private String myName;

	private static final Permission[] ALL_PERMISSIONS = { VIEW, EDIT,
			SET_PERMISSIONS, REMOVE };

	private Permission(String name) {
		myName = name;
	}

	public static Permission forName(String permissionName) {
		String upperName = permissionName.toUpperCase();
		for (int i = 0; i < ALL_PERMISSIONS.length; i++) {
			Permission permission = ALL_PERMISSIONS[i];
			if (permission.toString().equals(upperName))
				return permission;
		}

		throw new IllegalArgumentException("Permission not found with name: "
				+ permissionName);
	}

	Object readResolve() throws ObjectStreamException {
		for (int i = 0; i < ALL_PERMISSIONS.length; i++) {
			Permission permission = ALL_PERMISSIONS[i];
			if (myName.equals(permission.myName))
				return permission;
		}

		throw new IllegalStateException(
				"No permission can be deserialized with name: " + myName);
	}

	public String toString() {
		return myName;
	}

	public abstract boolean checkAgainst(
			IPermissionDelegate permissiondelegate, User user, Object target);
}
